import type { Model } from '../aiModels'
import { useAIStore } from '@/stores'
import { BaseAIProvider, type StreamContentOptions } from './base'

// Token缓存接口
interface TokenCache {
  token: string
  expiresAt: number // 过期时间戳（秒）
}

// 添加检查和纠正模型的函数
function validateAndFixModel(model: string): string {
  console.log(`用户选择的模型: ${model}`)
  return model
}

export class GitHubCopilotProvider extends BaseAIProvider {
  private tokenCache: TokenCache | null = null

  constructor() {
    super(
      `github-copilot`,
      `GitHub Copilot`,
      `GitHub Copilot API服务`,
      `https://api.githubcopilot.com`,
    )
  }

  getDefaultModels(): Model[] {
    return [
      {
        id: `copilot-chat`,
        name: `Copilot Chat`,
        maxTokens: 4096,
        available: true,
      },
      {
        id: `claude-3.5-sonnet`,
        name: `Claude 3.5 Sonnet`,
        maxTokens: 90000,
        available: true,
      },
      {
        id: `claude-3.7-sonnet`,
        name: `Claude 3.7 Sonnet`,
        maxTokens: 200000,
        available: true,
      },
      {
        id: `claude-3.7-sonnet-thought`,
        name: `Claude 3.7 Sonnet Thinking`,
        maxTokens: 200000,
        available: true,
      },
      {
        id: `gpt-3.5-turbo`,
        name: `GPT 3.5 Turbo`,
        maxTokens: 16384,
        available: true,
      },
      {
        id: `gpt-4`,
        name: `GPT 4`,
        maxTokens: 32768,
        available: true,
      },
      {
        id: `gpt-4o`,
        name: `GPT-4o`,
        maxTokens: 128000,
        available: true,
      },
      {
        id: `gpt-4o-mini`,
        name: `GPT-4o mini`,
        maxTokens: 128000,
        available: true,
      },
      {
        id: `o1`,
        name: `o1 (Preview)`,
        maxTokens: 200000,
        available: true,
      },
      {
        id: `o3-mini`,
        name: `o3-mini (Preview)`,
        maxTokens: 200000,
        available: true,
      },
      {
        id: `gemini-2.0-flash-001`,
        name: `Gemini 2.0 Flash`,
        maxTokens: 1000000,
        available: true,
      },
    ]
  }

  // 获取Github Copilot Token
  private async getCopilotToken(apiKey: string, testUrl?: string): Promise<TokenCache> {
    try {
      console.log(`获取新的GitHub Copilot Token...`)

      // 使用本地代理URL替代直接访问GitHub API，避免CORS问题
      const proxyUrl = testUrl || `/copilot-token/copilot_internal/v2/token`
      
      const response = await fetch(proxyUrl, {
        method: `GET`,
        headers: {
          'Content-Type': `application/json`,
          'Accept': `application/json`,
          'authorization': `token ${apiKey}`,
          'editor-version': `Neovim/0.6.1`,
          'editor-plugin-version': `copilot.vim/1.16.0`,
          'user-agent': `GithubCopilot/1.155.0`
        },
      })

      if (!response.ok) {
        const errorText = await response.text().catch(() => `无法获取错误详情`)
        throw new Error(`获取GitHub Copilot Token失败 (${response.status}): ${errorText || response.statusText}`)
      }

      const data = await response.json()

      if (!data.token || !data.expires_at) {
        throw new Error(`获取的GitHub Copilot Token数据不完整`)
      }

      console.log(`成功获取GitHub Copilot Token`)
      return {
        token: data.token,
        expiresAt: data.expires_at,
      }
    }
    catch (error) {
      console.error(`获取GitHub Copilot Token出错:`, error)
      throw error
    }
  }

  // 确保Token有效，如果过期则重新获取
  private async ensureValidToken(apiKey: string): Promise<string> {
    const now = Math.floor(Date.now() / 1000) // 当前时间戳（秒）

    // 如果没有缓存或Token已过期，则重新获取
    if (!this.tokenCache || this.tokenCache.expiresAt <= now) {
      this.tokenCache = await this.getCopilotToken(apiKey)
    }
    else {
      console.log(`使用缓存的GitHub Copilot Token`)
    }

    return this.tokenCache.token
  }

  // 覆盖headers方法，因为Copilot有特殊需求
  async getHeaders(apiKey: string): Promise<Record<string, string>> {
    // 获取有效的Token
    const token = await this.ensureValidToken(apiKey)

    return {
      'Host': `api.githubcopilot.com`,
      'Connection': `keep-alive`,
      'sec-ch-ua': `"Not/A)Brand";v="8", "Chromium";v="126"`,
      'x-title': `Cherry Studio`,
      'http-referer': `https://cherry-ai.com`,
      'x-stainless-retry-count': `0`,
      'sec-ch-ua-mobile': `?0`,
      'authorization': `Bearer ${token}`, // 使用从GitHub获取的Token
      'User-Agent': `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) CherryStudio/1.1.8 Chrome/126.0.6478.234 Electron/31.7.6 Safari/537.36`,
      'content-type': `application/json`,
      'accept': `application/json`,
      'editor-version': `vscode/1.97.2`,
      'x-api-key': token,
      'sec-ch-ua-platform': `"macOS"`,
      'Sec-Fetch-Site': `cross-site`,
      'Sec-Fetch-Mode': `cors`,
      'Sec-Fetch-Dest': `empty`,
      'Accept-Language': `zh-CN`,
    }
  }

  // 实现流式内容请求方法
  async streamContent(options: StreamContentOptions): Promise<void> {
    const { prompt, apiKey, model, presetWords, onToken, onError, onFinish, setGenerating } = options

    if (setGenerating) {
      setGenerating(true)
    }

    try {
      // 验证必要的配置
      if (!apiKey) {
        throw new Error(`请先设置 API Key`)
      }

      console.log(`发送请求前使用的模型：${model}`)

      // 使用本地代理URL替代直接访问GitHub Copilot API
      const apiUrl = `/copilot-api/chat/completions`

      const response = await fetch(apiUrl, {
        method: `POST`,
        headers: await this.getHeaders(apiKey),
        body: JSON.stringify({
          model: model || `claude-3.7-sonnet-thought`,
          messages: [
            ...(presetWords || []).map(word => ({ role: `system`, content: word })),
            ...(typeof prompt === `string`
              ? [{ role: `user`, content: prompt }]
              : Array.isArray(prompt)
                ? prompt
                : [
                    { role: `system`, content: (prompt as { system?: string }).system || `` },
                    { role: `user`, content: (prompt as { user?: string }).user || `` },
                  ]
            ).filter(msg => msg.content),
          ],
          stream: true,
        }),
      })

      if (!response.ok) {
        const errorText = await response.text().catch(() => `无法获取错误详情`)
        console.error(`API错误：`, {
          状态码: response.status,
          状态文本: response.statusText,
          错误详情: errorText,
        })

        // 特殊处理模型不存在错误
        if (errorText.includes(`model`) && (errorText.includes(`not found`) || errorText.includes(`cannot find`))) {
          console.warn(`模型不可用错误：${errorText}`)
          throw new Error(`所选模型(${model})不可用，请选择其他模型或联系API提供商确认支持的模型列表`)
        }

        throw new Error(`API请求失败 (${response.status}): ${errorText || response.statusText}`)
      }

      // 使用基类的流式响应处理方法
      await this.processStreamResponse(response, onToken, onFinish, setGenerating)
    }
    catch (error) {
      if (setGenerating) {
        setGenerating(false)
      }
      console.error(`AI 请求失败:`, {
        错误信息: error instanceof Error ? error.message : String(error),
        模型: model,
      })
      onError?.(error instanceof Error ? error : new Error(String(error)))
    }
  }

  // 非流式内容请求方法
  async callContent(prompt: string | Array<{ role: string, content: string }> | { system?: string, user?: string }, apiKey: string, baseUrl: string): Promise<string> {
    try {
      // 从aiStore获取模型
      const aiStore = useAIStore()
      const selectedModel = aiStore.customModel || aiStore.selectedModel

      // 验证模型
      const validatedModel = validateAndFixModel(selectedModel)

      // 使用本地代理URL替代直接访问GitHub Copilot API
      const apiUrl = `/copilot-api/chat/completions`

      const response = await fetch(apiUrl, {
        method: `POST`,
        headers: await this.getHeaders(apiKey),
        body: JSON.stringify({
          model: validatedModel || `claude-3.7-sonnet-thought`,
          messages: typeof prompt === `string`
            ? [{ role: `user`, content: prompt }]
            : Array.isArray(prompt)
              ? prompt
              : [
                  { role: `system`, content: (prompt as { system?: string }).system || `` },
                  { role: `user`, content: (prompt as { user?: string }).user || `` },
                ],
          // 使用非流式响应
          stream: false,
        }),
      })

      if (!response.ok) {
        const errorText = await response.text().catch(() => `无法获取错误详情`)
        console.error(`callAI API错误：`, {
          状态码: response.status,
          状态文本: response.statusText,
          错误详情: errorText,
        })

        // 特殊处理模型不存在错误
        if (errorText.includes(`model`) && (errorText.includes(`not found`) || errorText.includes(`cannot find`))) {
          console.warn(`模型不可用错误：${errorText}`)
          throw new Error(`所选模型(${validatedModel})不可用，请选择其他模型或联系API提供商确认支持的模型列表`)
        }

        throw new Error(`API请求失败 (${response.status}): ${errorText || response.statusText}`)
      }

      const data = await response.json()
      return data.choices[0].message.content
    }
    catch (error) {
      console.error(`调用 AI 服务失败:`, error)
      throw error
    }
  }

  // 添加测试函数
  async testTokenConnection(apiKey: string): Promise<void> {
    try {
      // 直接使用fetch请求而不通过代理
      const startTime = Date.now()

      const response = await fetch(`https://api.github.com/copilot_internal/v2/token`, {
        method: `POST`,
        headers: {
          'Content-Type': `application/json`,
          'Accept': `application/json`,
          'authorization': `token ${apiKey}`,
          'editor-version': `Neovim/0.6.1`,
          'editor-plugin-version': `copilot.vim/1.16.0`,
          'user-agent': `GithubCopilot/1.155.0`,
          'host': `api.github.com`,
        },
      })

      const requestTime = Date.now() - startTime
      console.log(`【直接请求】响应时间: ${requestTime}ms, 状态: ${response.status} ${response.statusText}`)

      const responseText = await response.text()
      try {
        const data = JSON.parse(responseText)
        console.log(`【直接请求】响应数据:`, data)
      }
      catch (e) {
        console.log(`【直接请求】响应内容(非JSON):`, responseText)
      }

      // 测试使用另一个端点
      console.log(`【测试新端点】尝试使用新的GitHub Copilot端点...`)
      const newEndpointResponse = await fetch(`https://api.githubcopilot.com/tokens`, {
        method: `POST`,
        headers: {
          'Content-Type': `application/json`,
          'Accept': `application/json`,
          'authorization': `Bearer ${apiKey}`,
          'editor-version': `Neovim/0.6.1`,
          'editor-plugin-version': `copilot.vim/1.16.0`,
          'user-agent': `GithubCopilot/1.155.0`,
        },
      })

      console.log(`【测试新端点】响应状态: ${newEndpointResponse.status} ${newEndpointResponse.statusText}`)
      const newEndpointText = await newEndpointResponse.text()
      try {
        const data = JSON.parse(newEndpointText)
        console.log(`【测试新端点】响应数据:`, data)
      }
      catch (e) {
        console.log(`【测试新端点】响应内容(非JSON):`, newEndpointText)
      }

      // 测试通过代理

      // 测试路径1: 原始路径
      try {
        await this.getCopilotToken(apiKey)
      }
      catch (e: any) {
        console.log(`【测试代理】路径1失败:`, e.message)
      }

      // 测试路径2: 直接URL (不经过代理)
      console.log(`【测试代理】路径2: 直接访问 GitHub API`)
      try {
        await this.getCopilotToken(apiKey, `https://api.github.com/copilot_internal/v2/token`)
      }
      catch (e: any) {
        console.log(`【测试代理】路径2失败:`, e.message)
      }

      // 测试路径3: 新API路径
      console.log(`【测试代理】路径3: 新API路径`)
      try {
        await this.getCopilotToken(apiKey, `/copilot-api/tokens`)
      }
      catch (e: any) {
        console.log(`【测试代理】路径3失败:`, e.message)
      }

      // 添加更详细的请求状态输出
      console.log(`【测试完成】所有测试路径已尝试`)
    }
    catch (error) {
      console.error(`【测试失败】连接测试出错:`, error)
    }
  }
}
